package org.aman.generator.plugin;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;

import java.util.List;
import java.util.Properties;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.FullyQualifiedTable;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.config.CommentGeneratorConfiguration;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.JavaClientGeneratorConfiguration;
import org.mybatis.generator.config.JavaModelGeneratorConfiguration;
import org.mybatis.generator.config.SqlMapGeneratorConfiguration;

/**
 * @desc <p></p>
 * @author DaiJiangGuo
 * @date 2015年5月20日下午4:59:57
 */
public class AmanPluginConfig{
    public String newLine = "\n";
    public FullyQualifiedTable table;
    public Context context;
    public IntrospectedTable introspectedTable;
    public Properties properties;
    public FullyQualifiedJavaType pagerType;
    public JavaModelGeneratorConfiguration modelConfig;
    public SqlMapGeneratorConfiguration sqlMapConfig;
    public JavaClientGeneratorConfiguration clientMapConfig;
    public CommentGeneratorConfiguration commentConfig;

    public FullyQualifiedJavaType modelType;
    public FullyQualifiedJavaType mapperType;
    public FullyQualifiedJavaType serviceType;
    public FullyQualifiedJavaType serviceImplType;
    public FullyQualifiedJavaType actionType;

    //==========================  配置属性    ===============================
    //分页类型
    public String pagerConfig;
    public String pagerPref;

    //生成目录
    public String targetProject;
    public String targetProjectService;

    //service
    public String servicePackage;
    public String serviceExtends;
    public String serviceExt;

    public String serviceImplPackage;
    public String serviceImplExtends;
    public String serviceImplImplements;
    public String serviceImplExt;

    //action
    public String actionPackage;
    public String actionExtends;
    public String actionExt;
    public String actionImplements;

    //service 方法
    public String serviceMethod_save;
    public String serviceMethod_saveSelective;
    public String serviceMethod_deleteByPk;
    public String serviceMethod_updateByPk;
    public String serviceMethod_updateByPkSelective;
    public String serviceMethod_findByPk;
    public String serviceMethod_queryByMap;
    public String serviceMethod_queryByEntity;
    public String serviceMethod_queryByPager;

    public boolean service_gen;
    public boolean serviceMethod_gen_save = false;
    public boolean serviceMethod_gen_saveSelective;
    public boolean serviceMethod_gen_deleteByPk;
    public boolean serviceMethod_gen_updateByPk;
    public boolean serviceMethod_gen_updateByPkSelective;
    public boolean serviceMethod_gen_findByPk;
    public boolean serviceMethod_gen_queryByMap;
    public boolean serviceMethod_gen_queryByEntity;
    public boolean serviceMethod_gen_queryByPager;

    //action方法
    public String actionMethod_list;
    public String actionMethod_listTable;
    public String actionMethod_updPage;
    public String actionMethod_upd;
    public String actionMethod_addPage;
    public String actionMethod_add;
    public String actionMethod_detail;

    public boolean action_gen;
    public boolean actionMethod_gen_list;
    public boolean actionMethod_gen_listTable;
    public boolean actionMethod_gen_updPage;
    public boolean actionMethod_gen_upd;
    public boolean actionMethod_gen_addPage;
    public boolean actionMethod_gen_add;
    public boolean actionMethod_gen_detail;

    public AmanPluginConfig(Context context, IntrospectedTable introspectedTable, Properties properties) {
        super();
        this.context = context;
        this.introspectedTable = introspectedTable;
        this.properties = properties;
        this.table = introspectedTable.getFullyQualifiedTable();
        this.modelConfig = context.getJavaModelGeneratorConfiguration();
        this.sqlMapConfig = context.getSqlMapGeneratorConfiguration();
        this.clientMapConfig = context.getJavaClientGeneratorConfiguration();
        this.commentConfig = context.getCommentGeneratorConfiguration();
        initialized();
    }

    /**
     * @author DaiJiangGuo
     * @data 2015年5月20日 下午5:38:52
     */
    private void initialized() {
        this.pagerPref = def(val("pagerPref"), "params.");
        this.pagerConfig = def(val("pagerConfig"), "com.common.base.Pager");
        this.pagerType = new FullyQualifiedJavaType(this.pagerConfig);

        //生成目录
        this.targetProject = def(val("targetProject"), modelConfig.getTargetProject());
        this.targetProjectService = def(val("targetProjectService"), this.targetProject);

        //service
        String serviceModule = this.introspectedTable.getTableConfigurationProperty("module");
        serviceModule = StringUtils.isBlank(serviceModule) ? "" : ("." + serviceModule);
        this.servicePackage = def(val("servicePackage"), modelConfig.getTargetPackage()).replace(".{module}", serviceModule);
        this.serviceExtends = val("serviceExtends");
        this.serviceExt = def(val("serviceExt"), "Service");
        this.serviceImplPackage = def(val("serviceImplPackage"), modelConfig.getTargetPackage()).replace(".{module}", serviceModule);
        this.serviceImplExtends = val("serviceImplExtends");
        this.serviceImplImplements = val("serviceImplImplements");
        this.serviceImplExt = def(val("serviceImplExt"), "ServiceImpl");

        //action
        this.actionPackage = def(val("actionPackage"), modelConfig.getTargetPackage());
        this.actionExtends = val("actionExtends");
        this.actionExt = def(val("actionExt"), "Action");
        this.actionImplements = val("actionImplements");

        //service 方法
        this.serviceMethod_save = def(val("serviceMethod_save"), "save");
        this.serviceMethod_saveSelective = def(val("serviceMethod_saveSelective"), "saveSelective");
        this.serviceMethod_deleteByPk = def(val("serviceMethod_deleteByPk"), "deleteByPk");
        this.serviceMethod_updateByPk = def(val("serviceMethod_updateByPk"), "updateByPk");
        this.serviceMethod_updateByPkSelective = def(val("serviceMethod_updateByPkSelective"), "updateByPkSelective");
        this.serviceMethod_findByPk = def(val("serviceMethod_findByPk"), "findByPk");
        this.serviceMethod_queryByMap = def(val("serviceMethod_queryByMap"), "queryByMap");
        this.serviceMethod_queryByEntity = def(val("serviceMethod_queryByEntity"), "queryByEntity");
        this.serviceMethod_queryByPager = def(val("serviceMethod_queryByPager"), "queryByPager");

        //action方法
        this.actionMethod_list = def(val("actionMethod_list"), "list");
        this.actionMethod_listTable = def(val("actionMethod_listTable"), "listTable");
        this.actionMethod_updPage = def(val("actionMethod_updPage"), "updPage");
        this.actionMethod_upd = def(val("actionMethod_upd"), "upd");
        this.actionMethod_addPage = def(val("actionMethod_addPage"), "addPage");
        this.actionMethod_add = def(val("actionMethod_add"), "add");
        this.actionMethod_detail = def(val("actionMethod_detail"), "detail");


        this.service_gen = boolDef(val("service_gen"), false);
        this.serviceMethod_gen_save = boolDef(val("serviceMethod_gen_save"), false);
        this.serviceMethod_gen_saveSelective = boolDef(val("serviceMethod_gen_saveSelective"), false);
        this.serviceMethod_gen_deleteByPk = boolDef(val("serviceMethod_gen_deleteByPk"), false);
        this.serviceMethod_gen_updateByPk = boolDef(val("serviceMethod_gen_updateByPk"), false);
        this.serviceMethod_gen_updateByPkSelective = boolDef(val("serviceMethod_gen_updateByPkSelective"), false);
        this.serviceMethod_gen_findByPk = boolDef(val("serviceMethod_gen_findByPk"), false);
        this.serviceMethod_gen_queryByMap = boolDef(val("serviceMethod_gen_queryByMap"), false);
        this.serviceMethod_gen_queryByEntity = boolDef(val("serviceMethod_gen_queryByEntity"), false);
        this.serviceMethod_gen_queryByPager = boolDef(val("serviceMethod_gen_queryByPager"), false);

        this.action_gen = boolDef(val("action_gen"), false);
        this.actionMethod_gen_list = boolDef(val("actionMethod_gen_list"), false);
        this.actionMethod_gen_listTable = boolDef(val("actionMethod_gen_listTable"), false);
        this.actionMethod_gen_updPage = boolDef(val("actionMethod_gen_updPage"), false);
        this.actionMethod_gen_upd = boolDef(val("actionMethod_gen_upd"), false);
        this.actionMethod_gen_addPage = boolDef(val("actionMethod_gen_addPage"), false);
        this.actionMethod_gen_add = boolDef(val("actionMethod_gen_add"), false);
        this.actionMethod_gen_detail = boolDef(val("actionMethod_gen_detail"), false);

        this.modelType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        this.mapperType = new FullyQualifiedJavaType(introspectedTable.getMyBatis3JavaMapperType());
        this.serviceType = new FullyQualifiedJavaType(this.servicePackage + "." + table.getDomainObjectName() + serviceExt);
        this.serviceImplType = new FullyQualifiedJavaType(this.serviceImplPackage + "." + table.getDomainObjectName() + serviceImplExt);
        this.actionType = new FullyQualifiedJavaType(this.actionPackage + "." + table.getDomainObjectName() + actionExt);
    }

    public String def(String target, String defaultValue) {
        if (stringHasValue(target)) {
            return target;
        } else {
            return defaultValue;
        }
    }
    public String val(String target) {
        return properties.getProperty(target);
    }
    public boolean boolDef(String target, boolean defaultValue) {
        if (stringHasValue(target)) {
            if("false".equalsIgnoreCase(target)){
                return false;
            } else if("true".equalsIgnoreCase(target)){
                return true;
            }
        }
        return defaultValue;
    }

    public String genProperty(FullyQualifiedJavaType type){
        return type.getShortName().substring(0,1).toLowerCase() + type.getShortName().substring(1);
    }
    public static boolean isPkCol(List<IntrospectedColumn> pkCols, IntrospectedColumn col){
        if(CollectionUtils.isEmpty(pkCols)){
            return false;
        }
        for(IntrospectedColumn pk : pkCols){
            if(col.getActualColumnName() == pk.getActualColumnName()){
                return true;
            }
        }
        return false;
    }
}
